package org.ala.tiktools.rpc.kcp.netty.server.handler;

import io.netty.channel.ChannelPipeline;
import org.ala.tiktools.rpc.kcp.netty.NettyKcp;
import org.ala.tiktools.rpc.kcp.netty.server.KcpServerChannel;
import org.ala.tiktools.rpc.kcp.netty.server.KcpServerChildChannel;
import org.ala.tiktools.tools.TimestampTools;

import java.net.InetSocketAddress;

/**
 * ServerChannel负责的Creator
 *
 * @author ala
 * @date 2025-04-15 17:01
 */
public class KcpServerChannelCreator {
    /**
     *
     */
    protected KcpServerChannel serverChannel;
    public KcpServerChannelCreator(KcpServerChannel serverChannel) {
        this.serverChannel = serverChannel;
    }


    /**
     * 创建 或 获取KcpChannel
     * @param remoteAddress
     * @return
     */
    public KcpServerChildChannel getOrCreateKcpChannel(InetSocketAddress remoteAddress) {
        KcpServerChildChannel ch = serverChannel.getChildChannelMap().get(remoteAddress);
        if (ch == null) {
            ch = createChildChannel(remoteAddress);
            serverChannel.getChildChannelMap().put(remoteAddress, ch);
        }
        return ch;
    }
    /**
     *  创建ServeClientChannel
     */
    private KcpServerChildChannel createChildChannel(InetSocketAddress remoteAddress) {
        NettyKcp kcp = new NettyKcp(0, serverChannel.getOutput()); // temp conv, need to set conv in outter
        KcpServerChildChannel ch = new KcpServerChildChannel(serverChannel, kcp, remoteAddress);

        //  这里会触发KcpServerChannel的fireChannelRead，在KcpServerBootstrap里会触发init绑定事件
        ChannelPipeline pipeline = serverChannel.pipeline();
        pipeline.fireChannelRead(ch);
        pipeline.fireChannelReadComplete();

        if (!serverChannel.isScheduleUpdate()) { // haven't schedule update
            int current = TimestampTools.milliSeconds32();
            int tsUp = ch.kcpCheck(current);
            ch.kcpTsUpdate(tsUp);
            serverChannel.getWriter().scheduleUpdate(tsUp, current);
        }
        return ch;
    }
}
